#ifndef __HASHMAP_H__
#define __HASHMAP_H__



/*****************************************************/
/****

简单(char*, char*)键值对数据哈希表查找实现
主要功能：
插入，删除，查找，清空


*/



enum _Boolean { True = 1, False = 0 };
typedef enum _Boolean  Boolean;



// 键值对
typedef struct _sENTRY {
    void * key;                // 键
    void * value;              // 值
    struct _sENTRY * next;    // 冲突链表
}sENTRY;



// 哈希结构
typedef struct {
	int listSize;       // 数组总元素个数
    int size;           // 实时存储键值对数据个数
    int clash_num;		// 冲突次数
    Boolean autoAssign; // 设定是否根据当前数据量动态调整内存大小，默认开启

    sENTRY *list;       // 存储区域
      
}sHASHMAP;

// 迭代器结构
typedef struct {
    sENTRY *entry;    	// 迭代器当前指向
    int count;      	// 迭代次数
    int index;   		// 取出键值对的哈希值
    sHASHMAP *hashMap;
}sHASHMAP_ITERATOR;


/*********************************************************************************/

/*创建哈希表，初始化*/
sHASHMAP *hashMap_create(void);

/*哈希函数接口*/ 
static int key2index(sHASHMAP * hashMap, const void* key);


/*
新加和修改一个键值对

如果key在哈希表中已经存在，就修改value，否则就是新加一个节点。
本函数添加的是在堆空间新建的数据拷贝
*/
void hashMap_insert(sHASHMAP * hashMap, const void * key, const void * value);


/*
buff_len必须 > value的长度，value的长度可由hashMap_exists()获取
注意：无论是否找到，一定执行memset(ret_buff, 0x00, buff_len);
以避免在未找到情况下，误以为ret_buff数据为value的值
也可以判断返回值来确定是否找到
未找到，返回-1
找到，返回看作字符串时value的长度
*/
int hashMap_get_value(sHASHMAP * hashMap, const void * key, void * ret_buff, int buff_len);
int hashMap_find(sHASHMAP * hashMap, const void * key, void * ret_buff, int buff_len);
int hashMap_search(sHASHMAP * hashMap, const void * key, void * ret_buff, int buff_len);


/*用户释放value中的指针指向的空间，一般key是char*不会包含指针
*/
int hashMap_remove_user(sENTRY *entry);

/*
这里有很三种情况需要考虑
1.哈希表为空
2.相应数据不存在，已删除
3.删除成功

在理解<删除>为真正执行了删除动作的情况下（即下面实现），1、2返回False，3返回True
如果理解<删除>为 使哈希表中该键值对不存在，本函数无需返回，一定满足理解要求（可自行修改，或者调用者不判断返回值）。
*/
int hashMap_remove(sHASHMAP * hashMap, const void * key);

/*
判断key是否存在
存在，返回value长度，value长度>=0，看作字符串包括'\0'
不存，在返回-1
*/
int hashMap_exists(sHASHMAP * hashMap, const void * key);

/*清空哈希表，初始化为最初的8元素数组*/
void hashMap_clean(sHASHMAP * hashMap);
void hashMap_reset(sHASHMAP * hashMap);

/*清空哈希表，释放所有资源，传入管理结构体的指针的地址*/
void hashMap_delete(sHASHMAP ** hashMap);


/*根据new_listSize指向的空间大小，重新映射分配数据*/
void hashMap_resize(sHASHMAP * hashMap, int new_listSize);




/**迭代器，可用于逐个取出元素**/
// 创建哈希结构迭代器
sHASHMAP_ITERATOR* hashMap_Iterator_create(sHASHMAP * hashMap);

// 迭代器是否有下一个
Boolean hashMap_Iterator_hasNext(sHASHMAP_ITERATOR* iterator);

// 迭代到下一次
sHASHMAP_ITERATOR* hashMap_Iterator_next(sHASHMAP_ITERATOR* iterator);

// 释放迭代器内存
void hashMap_Iterator_free(sHASHMAP_ITERATOR** iterator);


/*********************************************************************************/


#endif // !__HASHMAP_H__